package chapter11;

import redis.clients.jedis.Jedis;

public class LimitByCount {
    /**
     * 判断是否可以访问
     * 通过Redis和Lua脚本确保在限定时间内访问次数不超过限定次数
     *
     * @param jedis      Redis客户端，用于执行Redis命令
     * @param moduleName 模块名称，用于在Redis中区分不同的模块
     * @param limitTime  限定时间，单位为秒，在这个时间内访问次数不能超过limitNum
     * @param limitNum   限定次数，在limitTime内允许的最大访问次数
     * @return 如果当前访问未超过限制，则返回true，否则返回false
     */
    public static boolean canVisit(Jedis jedis, String moduleName, int limitTime, int limitNum) {
        // Lua脚本，用于在Redis中执行逻辑判断和数据更新
        // 这段脚本的作用是检查和更新模块的访问次数，确保在限定时间内访问次数不超过限定次数
        String luaScript = "local moduleName=KEYS[1]\n" +
                "local limitCount=tonumber(ARGV[1])\n" +
                "local current=tonumber(redis.call('get',moduleName) or \"0\")\n" +
                "if(current+1>limitCount) then\n" +
                "  return 0\n" +
                "else\n" +
                "  redis.call('incrby',moduleName,1)\n" +
                "  redis.call('expire',moduleName,tonumber(ARGV[2]))\n" +
                "  return current+1\n" +
                "end";
        // 执行Lua脚本，判断返回值是否为1，从而决定是否可以访问
        String result = jedis.eval(luaScript, 1, moduleName, String.valueOf(limitNum), String.valueOf(limitTime)).toString();
        return !result.equals("0");
    }
}
